#!/bin/bash
# This script installs Kubernetes components (kubeadm, kubelet, kubectl) on a Linux machine.
# supports installation on both Ubuntu and CentOS operating systems
# Usage: ./install.sh [--online|-o] [--force|-f] [--version=<version>] [--group=<group>] [--pkg-mirror=<https://xxx>][--image-mirror=<https://xxx>][--rm|--remove] [--clean|-c] [--downloadonly|-d]
# Options:
#   --online|-o: install using online method
#   --force|-f: force installation
#   --version=<version>: specify the version to be installed
#   --group=<group>: specify the group to be configured, default is root
#   --pkg-mirror=<https://xxx>: specify the pkg mirror to be used, default is https://mirrors.ustc.edu.cn
#         eg: 1, https://mirrors.ustc.edu.cn
#             2, https://mirrors.tuna.tsinghua.edu.cn
#             3, https://mirrors.aliyun.com
#             4, http://mirrors.163.com
#             5, http://mirrors.cloud.tencent.com
#   --rm|--remove: uninstall kubeadm/kubelet/kubectl
#   --clean|-c: remove downloaded files
#   --downloadonly|-d: only download kubeadm/kubelet/kubectl package, do not install
#   example1, download 20.10.20 pkg: 
#           ./install.sh --version=20.10.20 --force --downloadonly
#   example2, install 20.10.20 then clean pkg: 
#          ./install.sh --version=20.10.20 --clean
#   example3, install 20.10.20 using apt or yum, and force installation: 
#          ./install.sh --version=20.10.20 -fo
#   example4, install latest using apt or yum
#          ./install.sh --online, or ./install.sh -o
# Functionality:
# 0. This script supports installation on both Ubuntu and CentOS operating systems.
# 1. Specify the version to be installed TARGET_VERSION and whether to force if FORCE
# 2. Determine whether the local version current_version is >= the specified version TARGET_VERSION. If it is, do not install it. If --force is specified, force installation
# 3. Installation process:
#    1) Uninstall the local version
#    2) Call the official script https://get.docker.com to install the specified version
# 4. Configure group as the specified group, default is root
# 5. Configure the /etc/docker/daemon.json file
# 6. Configure and start the service

# 该脚本在 Linux 机器上安装 Kubernetes 组件（kubeadm、kubelet、kubectl）。适用于ubuntu或者centos
# 使用方法: ./install.sh [--online|-o] [--force] [--version=<version>] [--group=<group>] [--mirror=<https://xxx>] [--rm|--remove]
# Options:
# 选项:
#   --online|-o: 使用在线方法安装，即使用apt或者yum安装。不指定时，默认为使用二进制包安装，如果没有二进制包，则自动下载。
#   --force|-f: 强制安装
#   --version=<version>: 指定要安装的版本。如果指定的是在线安装，则自动获得最新版本，如果是离线安装，则默认为20.10.24
#   --group=<group>: 指定要配置的组，默认为 root
#   --pkg-mirror=<https://xxx>: 指定要使用的软件包镜像源，用于下载apt或者yum下载kubeadm/kubelet/kubectl包，默认为 https://mirrors.ustc.edu.cn
#         例如: 1, https://mirrors.ustc.edu.cn
#             2, https://mirrors.tuna.tsinghua.edu.cn
#             3, https://mirrors.aliyun.com
#             4, http://mirrors.163.com
#             5, http://mirrors.cloud.tencent.com
#   --rm|--remove: 卸载 kubeadm/kubelet/kubectl
#   --clean|-c: 删除已下载的文件，单独指定，则为删除安装包，加上其它flag，则为安装后自动删除安装包
#   --downloadonly|-d: 仅下载 kubeadm/kubelet/kubectl包但不安装
#   示例1，下载20.10.20版本的包: 
#           ./install.sh --version=20.10.20 --force --downloadonly
#   示例2，安装20.10.20版本，然后清理包: 
#          ./install.sh --version=20.10.20 --clean
#   示例3，使用在线方法(apt或者yum)安装20.10.20版本，并强制安装: 
#          ./install.sh --version=20.10.20 -fo
#   示例4，使用apt或者yum安装最新版本
#          ./install.sh --online 或者 ./install.sh -o
#实现功能：
#0，适用于ubuntu或者centos
#1，指定要安装的版本TARGET_VERSION，以及是否强制如果FORCE
#2，判断本地版本current_version是否>=指定版本TARGET_VERSION，如果是，则不安装，如果指定--force，则强制安装
#3，安装过程：
#     1)卸载本地版本
#     2)在线安装(--online)：调用官方脚本https://get.docker.com安装指定的版本
#     3)离线安装：下载官方的二进制包安装，然后解压安装
#4，配置group 为指定的group, 默认为root
#5，配置/etc/kubernetes/kubelet.conf文件
#6，配置和启动service
TOP_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." &> /dev/null && pwd )"
CUR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

PACKAGE_MANAGER=$((command -v apt-get > /dev/null && echo apt-get) \
    || (command -v yum > /dev/null && echo yum) \
    || (echo "Neither apt-get nor yum is installed, please install one of them first." && exit 1))
#package mirros & docker images mirrors
#linux软件镜像站和docker镜像加速站，可自行选取
#ustc 中科大
#DEFAULT_PKG_MIRROR=https://mirrors.ustc.edu.cn
#DEFAULT_IMG_MIRROR=https://docker.mirrors.ustc.edu.cn
#tsinghua 清华
#DEFAULT_PKG_MIRROR=https://mirrors.tuna.tsinghua.edu.cn
#DEFAULT_IMG_MIRROR=https://docker.mirrors.tuna.tsinghua.edu.cn
#aliyun 阿里云
DEFAULT_PKG_MIRROR="https://mirrors.aliyun.com"
DEFAULT_IMG_MIRROR=https://9zufkov1.mirror.aliyuncs.com
#163 网易
#DEFAULT_PKG_MIRROR=http://mirrors.163.com
#DEFAULT_IMG_MIRROR=http://hub-mirror.c.163.com
#tecent 腾讯
#DEFAULT_PKG_MIRROR=http://mirrors.cloud.tencent.com
#DEFAULT_IMG_MIRROR=https://mirror.ccs.tencentyun.com
#docker官方的image加速站
#DEFAULT_IMG_MIRROR=https://registry.docker-cn.com

#二进制包下载路径
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
GH_PROXY=${URL_githubProxy:-https://ghproxy.com/}
RELEASE_VERSION="v0.15.1"
KUBELET_SERVICE_URL=${GH_PROXY}${URL_kubelet_service:-"https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service"}
KUBEADM_CONF_URL=${GH_PROXY}${URL_kubeadm_conf:-"https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf"}
LATEST_VERSION_URL="https://dl.k8s.io/release/stable.txt"
LATEST_VERSION="$(curl -fsSL ${LATEST_VERSION_URL} 2>/dev/null)"

#TARGET_VERSION是可变的，使用方法，在TARGET_VERSION确定后，执行BINARY_URL_PATH=$(eval echo $BINARY_URL_PATH)
BINARY_URL_PATH=https://dl.k8s.io/release/v\${TARGET_VERSION}/bin/linux/${ARCH}
KUBELET_BIN_URL=${URL_kubelet_bin:-"${BINARY_URL_PATH}/kubelet"}
KUBEADM_BIN_URL=${URL_kubeadm_bin:-"${BINARY_URL_PATH}/kubeadm"}
KUBECTL_BIN_URL=${URL_kubectl_bin:-"${BINARY_URL_PATH}/kubectl"}
KUBECTL_SHA256_URL=${URL_kubectl_sha256:-"https://dl.k8s.io/v\${TARGET_VERSION}/bin/linux/${ARCH}/kubectl.sha256"}


DOWNLOAD_DIR=$CUR_DIR/package
DEFAULT_VERSION=${LATEST_VERSION:-1.21.11}
BIN_DIR=/usr/local/bin
# 检查是否有curl和wget
HAS_CURL="$(command -v curl >/dev/null 2>&1 && echo true || echo false)"
HAS_WGET="$(command -v wget >/dev/null 2>&1 && echo true || echo false)"
bash_xc="bash -xc"
if ! $HAS_CURL && ! $HAS_WGET; then
  echo "Either curl or wget is required"
  exit 1
fi

##include scripts##
##include end##


#usage: download_url <url> [target] 
download_url() {
  local target
  local url=$1
  local remote_file=""
  
  if [ $# -eq 2 ]; then
    target=$2
  elif [ $# -eq 1 ]; then 
    target=${1##*/}
  else
    echo "cmd err, usage: download_url <url> [target]"
    return 1
  fi
  if [ ! -f "$target" ] || ${FORCE} ; then
    if $HAS_CURL; then
      $bash_xc "curl -fsSL $url -o $target"
      if [ $? -ne 0 ]; then
        echo "curl or wget failed"
        return 3
      fi
    elif $HAS_WGET; then
      $bash_xc "wget -q $url -O $target"
      if [ $? -ne 0 ]; then
        echo "curl or wget failed"
        return 3
      fi
    fi
    echo "get $(basename $target) successfully"
    return 0
  else
    echo "do not get $(basename $url): file exist or force=${FORCE} "
    return 0
  fi
  return 0
}

download_url_until_succeed() {
  local target
  local url=$1
  
  if [ $# -eq 2 ]; then
    target=$2
  elif [ $# -eq 1 ]; then 
    target=${1##*/}
  else
    echo "cmd err, usage: download_url <url> [target]"
    return 1
  fi
  echo "download $url $target"
  
  while ! download_url $url $target; do
    sleep 5
  done
}


# Remove any lock files that may be preventing package manager from running.
# 删除可能阻止包管理器运行的任何锁定文件
clean_locks() {
    if [ "$PACKAGE_MANAGER" == "apt-get" ]; then
        rm -rf /var/lib/dpkg/lock
        rm -rf /var/lib/dpkg/lock-frontend
        rm -rf /var/cache/apt/archives/lock
    elif [ "$PACKAGE_MANAGER" == "yum" ]; then
        rm -rf /var/run/yum.pid
        rm -rf /var/run/yum.pid.old
        # rm -rf /var/cache/yum/*
    fi
}

#set -x
# Define functions to check version and install Kubernetes components

# check if the current version is less than the target version.
# 检查当前版本是否小于目标版本。
check_version_lt() {
    test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" != "$1"
}

# check if the current version is greater than or equal to the target version.
# 检查当前版本是否大于或等于目标版本。
check_version_ge() {
    test "$(echo "$@" | tr " " "\n" | sort -rV | head -n 1)" == "$1"
}

# get the latest version of Kubernetes components.
# 获取 Kubernetes 组件的最新版本。
get_latest_version() {
    local regex='[0-9]+\.([0-9]+)\.([0-9]+)'
    if [ "$PACKAGE_MANAGER" == "apt-get" ]; then
        echo $(apt-cache madison kubeadm | head -1 | grep -Eo "$regex")
    elif [ "$PACKAGE_MANAGER" == "yum" ]; then
        echo $(yum list kubeadm --showduplicates | grep -Eo "$regex" | sort -rV | head -1)
    fi
}

get_default_version() {
    if $ONLINE; then
        echo $(get_latest_version)
    else
        echo "$DEFAULT_VERSION"
    fi
}

# Check if Kubernetes components are installed and if they need to be upgraded
kubernetes_needs_installation() {
    if [ -x "$(command -v kubeadm)" ]; then
        CURRENT_VERSION=$(kubeadm version -o short)
        #echo "Current version: $current_version, target version: $TARGET_VERSION"
        if [ -z "$TARGET_VERSION" ] && [ "$FORCE" = "false" ]; then
            echo "Current version is $CURRENT_VERSION, use '--force=true' or '--verion=<version> to install as desired"
            return 1
        elif check_version_ge "$CURRENT_VERSION" "$TARGET_VERSION" && [ "$FORCE" != "true" ]; then
            echo "Current version ($CURRENT_VERSION) >= target version($TARGET_VERSION), and force=$FORCE; no need to install"
            return 1
        fi
    fi
    return 0
}
# Remove all Docker related files and services
# 删除docker所有的文件
remove_kubernetes() {
    set -x
    systemctl stop kubelet > /dev/null 2>&1
    rm -rf /etc/kubernetes
    rm -rf $BIN_DIR/{kubeadm,kubectl,kubelet}
    rm -rf /etc/systemd/system/kubelet.service
    rm -rf /etc/systemd/system/kubelet.service.d
    set +x
}
# deletes the old version of Kubernetes components.
# 删除旧版本的 Kubernetes 组件。
delete_old_version() {
    if [ -z "$CURRENT_VERSION" ]; then
        if [ -x "$(command -v kubeadm)" ]; then
            CURRENT_VERSION=$(kubeadm version -o short)
            CURRENT_VERSION=${CURRENT_VERSION#*v}
        elif [ -x "$(command -v kubectl)" ]; then
            CURRENT_VERSION=$(kubectl version --short | grep Client | awk '{print $3}')
            CURRENT_VERSION=${CURRENT_VERSION#*v}
        elif [ -x "$(command -v kubelet)" ]; then
            CURRENT_VERSION=$(kubelet --version| awk -F " v" '{print $2}')
        else
            echo "Kubernetes kubeadm are not installed"
            #return
        fi
    fi
    echo "Delete version $CURRENT_VERSION ..."

    clean_locks
    systemctl stop kubelet
    if [ "$PACKAGE_MANAGER" == "apt-get" ]; then
        local pkgs=$(dpkg -l | grep -E 'kubeadm|kubelet|kubectl' | awk '{print $2}')
        if [ -n "$pkgs" ] ; then
            set -x
            apt-get remove -y $pkgs > /dev/null 2>&1
            apt-get autoremove -y > /dev/null
            apt-get autoclean -y > /dev/null
            set +x
        fi
    elif [ "$PACKAGE_MANAGER" == "yum" ]; then
        local pkgs=$(rpm -qa | grep -E 'kubeadm|kubelet|kubectl' | awk '{print $1}')
        if [ -n "$pkgs" ] ; then
            set -x
            yum remove -y $pkgs > /dev/null 2>&1
            yum autoremove -y > /dev/null
            yum clean all > /dev/null
            set +x
        fi
    fi

    [ "$GROUP" == "kubelet" ] && groupdel kubelet > /dev/null 2>&1
    remove_kubernetes
}

# Update package manager
add_repo() {
    echo "add kubernetes repo"
    if [ "$PACKAGE_MANAGER" == "apt-get" ]; then
        if [ $PKG_MIRROR == "https://mirrors.aliyun.com" ]; then
            bash -xc "curl -s ${PKG_MIRROR}/kubernetes/apt/doc/apt-key.gpg | apt-key add -"
        fi
        cat >/etc/apt/sources.list.d/kubernetes.list <<-EOF 
deb ${PKG_MIRROR}/kubernetes/apt/ kubernetes-xenial main
EOF
    elif [ "$PACKAGE_MANAGER" == "yum" ]; then
        cat >/etc/yum.repos.d/kubernetes.repo <<-EOF
[kubernetes]
name=Kubernetes
baseurl=${PKG_MIRROR}/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=${PKG_MIRROR}/kubernetes/yum/doc/yum-key.gpg ${PKG_MIRROR}/kubernetes/yum/doc/rpm-package-key.gpg
EOF
    fi
    if [ "$PACKAGE_MANAGER" == "apt-get" ]; then
        echo "update packages: apt-get update ... "
        apt-get update -y > /dev/null 2>&1
    elif [ "$PACKAGE_MANAGER" == "yum" ]; then
        echo "update packages: yum makecache ... "
        yum makecache -y > /dev/null 2>&1
    fi
}

create_kubeadm_conf() {
    mkdir -p /etc/systemd/system/kubelet.service.d
    cat >/etc/systemd/system/kubelet.service.d/10-kubeadm.conf <<EOF
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet \$KUBELET_KUBECONFIG_ARGS \$KUBELET_CONFIG_ARGS \$KUBELET_KUBEADM_ARGS \$KUBELET_EXTRA_ARGS
EOF
}
# install Kubernetes components online.
# 在线安装 Kubernetes 组件。
install_kubernetes_online() {
    local count=0
    clean_locks
    if [ "$PACKAGE_MANAGER" == "yum" ]; then
      bash -xc "yum install -y kubeadm-$TARGET_VERSION kubelet-$TARGET_VERSION kubectl-$TARGET_VERSION --disableexcludes=kubernetes"
    elif [ "$PACKAGE_MANAGER" == "apt-get" ]; then
      bash -xc "apt-get install -y kubeadm=${TARGET_VERSION}-00 kubelet=${TARGET_VERSION}-00 kubectl=${TARGET_VERSION}-00"
    fi
    set -x
    create_kubeadm_conf
    systemctl enable kubelet
    systemctl daemon-reload
    systemctl restart kubelet > /dev/null 2>&1
    set +x
    while true; do
      st=$(systemctl is-active kubelet)
      case $st in
          activating)
              sleep 1
              ;;
          failed|inactive)
              if [ -n "$(systemctl status kubelet | grep "Loaded: masked")" ] ; then
                systemctl unmask kubelet
          fi              
              let count=count+2
              if [ $count -eq 30 ]; then
                  echo "timeout, start kubelet use cmd: systemctl restart kubelet"
                  break
              fi
              sleep $count
          systemctl enable kubelet
              systemctl daemon-reload
              systemctl restart kubelet
              ;;
          active)
              break
              ;;
      esac
    done
    systemctl status kubelet | head -8
    hash -r
    kubeadm version -o short
}

install_kubernetes_offline() {
    if [ ! -d $DOWNLOAD_DIR ]; then
        download_pkg
    fi
    set -x
    install -o root -g root -m 0755 $DOWNLOAD_DIR/bin/kubectl $BIN_DIR/kubectl
    chmod +x $DOWNLOAD_DIR/bin/{kubeadm,kubelet}
    cp -rf $DOWNLOAD_DIR/bin/{kubeadm,kubelet} $BIN_DIR/
	
	# 清除之前安装的损坏的文件
	rm -rf /etc/systemd/system/kubelet.service
    rm -rf /etc/systemd/system/multi-user.target.wants/kubelet.service
    rm -rf /var/lib/systemd/deb-systemd-helper-masked/kubelet.service
    rm -rf /var/lib/systemd/deb-systemd-helper-enabled/multi-user.target.wants/kubelet.service
    cp -rf $DOWNLOAD_DIR/systemd/kubelet.service /etc/systemd/system/kubelet.service
    sed -i "s:/usr/bin:${BIN_DIR}:g" /etc/systemd/system/kubelet.service

    sudo mkdir -p /etc/systemd/system/kubelet.service.d
    cp -rf $DOWNLOAD_DIR/systemd/10-kubeadm.conf /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    sed -i "s:/usr/bin:${BIN_DIR}:g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    #curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
    #sudo mkdir -p /etc/systemd/system/kubelet.service.d
    #curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    systemctl daemon-reload
	systemctl unmask kubelet
    systemctl enable --now kubelet
    hash -r
    kubeadm version -o short
    set +x
}
download_pkg() {
    bash -xc "mkdir -p $DOWNLOAD_DIR/{bin,systemd}"

    KUBEADM_BIN_URL=$(eval echo ${KUBEADM_BIN_URL})
    KUBELET_BIN_URL=$(eval echo ${KUBELET_BIN_URL})
    KUBECTL_BIN_URL=$(eval echo ${KUBECTL_BIN_URL})
    KUBECTL_SHA256_URL=$(eval echo ${KUBECTL_SHA256_URL})

    download_url_until_succeed ${KUBEADM_BIN_URL} $DOWNLOAD_DIR/bin/kubeadm
    download_url_until_succeed ${KUBELET_BIN_URL} $DOWNLOAD_DIR/bin/kubelet
    download_url_until_succeed ${KUBECTL_BIN_URL} $DOWNLOAD_DIR/bin/kubectl
    download_url_until_succeed ${KUBECTL_SHA256_URL} $DOWNLOAD_DIR/bin/kubectl.sha256

    #curl -fsSL --remote-name-all https://dl.k8s.io/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet,kubectl}
    #curl -LO https://dl.k8s.io/$RELEASE/bin/linux/amd64/kubectl.sha256
    if ! echo "$(cat $DOWNLOAD_DIR/bin/kubectl.sha256)  $DOWNLOAD_DIR/bin/kubectl" | sha256sum --check ; then
        echo "kubectl check failed"
        exit
    fi
    if [ ! -f $CUR_DIR/systemd/kubelet.service ]; then
        download_url_until_succeed $KUBELET_SERVICE_URL $CUR_DIR/systemd/kubelet.service
    fi
    cp -rf $CUR_DIR/systemd/kubelet.service $DOWNLOAD_DIR/systemd/kubelet.service

    if [ ! -f $CUR_DIR/systemd/10-kubeadm.conf ]; then
        download_url_until_succeed $KUBEADM_CONF_URL $CUR_DIR/systemd/10-kubeadm.conf
    fi
    cp -rf $CUR_DIR/systemd/10-kubeadm.conf $DOWNLOAD_DIR/systemd/10-kubeadm.conf
}


clean_download() {
    rm -rf $DOWNLOAD_DIR
}
function print_usage() {
    echo "Usage: $0 [--online|-o] [--force|-f] [--version=<version>] [--group=<group>] [--pkg-mirror=<https://xxx>][--image-mirror=<https://xxx>][--rm|--remove] [--clean|-c] [--downloadonly|-d]"
    echo "Options:"
    echo "  --online|-o: install using apt-get or yum(online=true), default install method is using binary(online=false)"
    echo "  --force|-f: force installation, default force=false"
    echo "  --version=<version>: specify the version to be installed, default is latest(online) or 20.10.24(apt/yum)"
    echo "  --group=<group>: specify the group to be configured, default is root"
    echo "  --pkg-mirror=<https://xxx>: specify the pkg mirror to be used, default is https://mirrors.ustc.edu.cn"
    echo "         eg: 1, https://mirrors.ustc.edu.cn"
    echo "             2, https://mirrors.tuna.tsinghua.edu.cn"
    echo "             3, https://mirrors.aliyun.com"
    echo "             4, http://mirrors.163.com"
    echo "             5, http://mirrors.cloud.tencent.com"
    echo "  --rm|--remove: uninstall Kubernetes"
    echo "  --clean|-c: remove downloaded files"
    echo "  --downloadonly|-d: only download kubernetes package, do not install"
    echo "  example1, download 1.21.11 binary pkg: "
    echo "          ./install.sh --version=1.21.11 --force --downloadonly"
    echo "  example2, install 20.10.20 using binary pkg, and then clean binary pkg" 
    echo "         ./install.sh --version=1.21.11  --clean"
    echo "  example3, install 20.10.20 using online method(by apt or yum), and force installation:" 
    echo "         ./install.sh --version=1.21.11  -fo"
}

#
#=====================main func ==============================
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root"
    exit 1
fi

#清除旧版本的影响，保证command -v命令得到正确的结果
hash -r

ARGS=$#

# Parse command line arguments
while [[ $# -gt 0 ]]
do
    key="$1"
    case $key in
    --online|-o)
        ONLINE=true
        shift
        ;;
    --clean|-c)
        if [[ $ARGS -eq 1 ]]; then
            clean_download
            exit 0
        fi
        AUTOCLEAN=true
        shift
        ;;
    --downloadonly|-d)
        DOWNLOAD_ONLY=true
        shift
        ;;
    --force|-f)
        FORCE=true
        shift
        ;;
    --group=*)
        GROUP="${key#*=}"
        shift
        ;;
    --group)
        shift
        GROUP="$1"
        shift
        ;;
    --pkg-mirror=*)
        PKG_MIRROR="${key#*=}"
        shift
        ;;
    --pkg-mirror)
        shift
        PKG_MIRROR="$1"
        shift
        ;;
    --version)
        shift
        TARGET_VERSION="${key}"
        shift
        ;;
    --version=*)
        TARGET_VERSION="${key#*=}"
        shift
        ;; 
    --help)
        print_usage
        exit 1
        ;;
    --rm|--remove)
        echo "Kubernetes components uninstall..."
        delete_old_version
        exit 1
        ;;
    -[^-]*)
        for ((i=1; i<${#key}; i++)); do
          case "${key:$i:1}" in
            o) ONLINE=true ;;
            f) FORCE=true ;;
            c) AUTOCLEAN=true ;;
            d) DOWNLOAD_ONLY=true ;;
            *) print_usage; exit 1 ;;
          esac
        done
        shift    
        ;;
    *)    # unknown option
        print_usage
        exit 1
        ;;
    esac
done

ONLINE=${ONLINE:-false}
PKG_MIRROR=${PKG_MIRROR:-$DEFAULT_PKG_MIRROR}
FORCE=${FORCE:-false}
GROUP=${GROUP:-root}
DOWNLOAD_ONLY=${DOWNLOAD_ONLY:-false}
AUTOCLEAN=${AUTOCLEAN:-false}

#设置软件安装源，从而获得最新版本
$ONLINE && add_repo
TARGET_VERSION=${TARGET_VERSION:-$(get_default_version)}

echo "targetVersion=$TARGET_VERSION force=$FORCE online=$ONLINE"
echo "downloadonly=$DOWNLOAD_ONLY group=$GROUP pkg-mirror=$PKG_MIRROR autoClean=$AUTOCLEAN"
if ! $ONLINE; then
    echo "binary package download url=https://dl.k8s.io/release/v${TARGET_VERSION}/bin/linux/${ARCH}"
fi

if $ONLINE && $DOWNLOAD_ONLY; then
    echo "Err: downloadonly used only in offline mode"
    exit 1
fi
if $DOWNLOAD_ONLY ; then
    download_pkg
    exit 0
fi
# Main script
if kubernetes_needs_installation; then
    [ -n "$CURRENT_VERSION" ] && delete_old_version

    echo "Install version $TARGET_VERSION ..."
    if $ONLINE ; then
        install_kubernetes_online
    else
        install_kubernetes_offline
    fi
    $AUTOCLEAN && clean_download
fi

